package logger

import (
	"context"
	"fmt"
	"go.uber.org/zap"
	"io"
	"os"
)

var _ LoggerHelper = &ZapLogger{}

func (l *ZapLogger) GetOutWriter() io.Writer {
	if l.outWriteSyncer == nil {
		return os.Stdout
	}
	return l.outWriteSyncer
}

func (l *ZapLogger) Debug(msg string) {
	if l.withSugar {
		l.sugarLogger.Debug(msg)
	} else {
		l.Logger.Debug(msg)
	}
}

func (l *ZapLogger) DebugF(format string, v ...interface{}) {
	if l.withSugar {
		l.sugarLogger.Debugf(format, v...)
	} else {
		msg := fmt.Sprintf(format, v...)
		l.Logger.Debug(msg)
	}
}

func (l *ZapLogger) DebugContext(ctx context.Context, msg string) {
	fields := l.logFields(ctx, zap.DebugLevel, msg)
	if l.withSugar {
		l.sugarLogger.Debug(msg, fields)
	} else {
		l.Logger.Debug(msg, fields...)
	}
}

func (l *ZapLogger) DebugContextF(ctx context.Context, format string, v ...interface{}) {
	msg := fmt.Sprintf(format, v...)
	fields := l.logFields(ctx, zap.DebugLevel, msg)
	if l.withSugar {
		l.sugarLogger.Debug(msg, fields)
	} else {
		l.Logger.Debug(msg, fields...)
	}
}

func (l *ZapLogger) Info(msg string) {
	if l.withSugar {
		l.sugarLogger.Info(msg)
	} else {
		l.Logger.Info(msg)
	}
}

func (l *ZapLogger) InfoF(format string, v ...interface{}) {
	if l.withSugar {
		l.sugarLogger.Infof(format, v...)
	} else {
		msg := fmt.Sprintf(format, v...)
		l.Logger.Info(msg)
	}
}

func (l *ZapLogger) InfoContext(ctx context.Context, msg string) {
	fields := l.logFields(ctx, zap.DebugLevel, msg)
	if l.withSugar {
		l.sugarLogger.Info(msg, fields)
	} else {
		l.Logger.Info(msg, fields...)
	}
}

func (l *ZapLogger) InfoContextF(ctx context.Context, format string, v ...interface{}) {
	msg := fmt.Sprintf(format, v...)
	fields := l.logFields(ctx, zap.DebugLevel, msg)
	if l.withSugar {
		l.sugarLogger.Info(msg, fields)
	} else {
		l.Logger.Info(msg, fields...)
	}
}

func (l *ZapLogger) Warn(msg string) {
	if l.withSugar {
		l.sugarLogger.Warn(msg)
	} else {
		l.Logger.Warn(msg)
	}
}

func (l *ZapLogger) WarnF(format string, v ...interface{}) {
	if l.withSugar {
		l.sugarLogger.Warnf(format, v...)
	} else {
		msg := fmt.Sprintf(format, v...)
		l.Logger.Warn(msg)
	}
}

func (l *ZapLogger) WarnContext(ctx context.Context, msg string) {
	fields := l.logFields(ctx, zap.DebugLevel, msg)
	if l.withSugar {
		l.sugarLogger.Warn(msg, fields)
	} else {
		l.Logger.Warn(msg, fields...)
	}
}

func (l *ZapLogger) WarnContextF(ctx context.Context, format string, v ...interface{}) {
	msg := fmt.Sprintf(format, v...)
	fields := l.logFields(ctx, zap.DebugLevel, msg)
	if l.withSugar {
		l.sugarLogger.Warn(msg, fields)
	} else {
		l.Logger.Warn(msg, fields...)
	}
}

func (l *ZapLogger) Error(msg string) {
	if l.withSugar {
		l.sugarLogger.Error(msg)
	} else {
		l.Logger.Error(msg)
	}
}

func (l *ZapLogger) ErrorF(format string, v ...interface{}) {
	if l.withSugar {
		l.sugarLogger.Errorf(format, v...)
	} else {
		msg := fmt.Sprintf(format, v...)
		l.Logger.Error(msg)
	}
}

func (l *ZapLogger) ErrorContext(ctx context.Context, msg string) {
	fields := l.logFields(ctx, zap.DebugLevel, msg)
	if l.withSugar {
		l.sugarLogger.Error(msg, fields)
	} else {
		l.Logger.Error(msg, fields...)
	}
}

func (l *ZapLogger) ErrorContextF(ctx context.Context, format string, v ...interface{}) {
	msg := fmt.Sprintf(format, v...)
	fields := l.logFields(ctx, zap.DebugLevel, msg)
	if l.withSugar {
		l.sugarLogger.Error(msg, fields)
	} else {
		l.Logger.Error(msg, fields...)
	}
}
